package net.sansi.v3correctserver.service.correct.bright;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.sansi.v3correctserver.entity.IntPoint;
import net.sansi.v3correctserver.entity.image.RecImage;
import net.sansi.v3correctserver.entity.photorec.LedNode;
import net.sansi.v3correctserver.service.photorec.rec.RecBase;
import net.sansi.v3correctserver.util.Matrix;
import net.sansi.v3correctserver.util.MonotoneUtil;

import java.util.Comparator;
import java.util.List;

/**
 * Created by Fang
 * create time : 2024/12/20
 * IDE : IntelliJ IDEA
 * <p>
 * 通过 full 1x1 相片来进行矫正
 */

@Getter
@Setter
public class RectBrightCorrectFull extends RecBase {

    Params params;
    int disX = 0;
    int disY = 0;
    int width = 0;
    int height = 0;


    private Matrix<double[]> result;

    private double targetBright;

    public RectBrightCorrectFull(Params params) {
        super(params.ledPhoto, params.blackPhoto, params.fence);
        this.params = params;
        width = params.leds.getWidth();
        height = params.leds.getHeight();
        result = params.getResult();
        disX = params.distanceX / params.span / 2;
        disY = params.distanceY / params.span / 2;
    }

    public RectBrightCorrectFull toCorrect() {
        targetBright = computeTargetBrightness();
        params.leds.foreach((x, y, led) -> {
            if (led == null) return;
            double scale = led.brightness / targetBright;
            result.get(x, y)[getParams().colorIdx] = scale * params.k;
        });
        return this;
    }

    public double computeTargetBrightness() {
        int size = width * height;
        MonotoneUtil<Double> mon = new MonotoneUtil<>((int) Math.max(size * 0.01, 1),
                Comparator.comparingDouble(a -> a));
        params.leds.foreach((x, y, led) -> {
            if (led == null) return;
            mon.add(getLedBrightness(led));
        });
        return mon.get();
    }

    public double getLedBrightness(LedNode led) {
        IntPoint p = led.getPhotoPos();
        led.brightness = 0;
        for (int x = p.getX() - disX; x <= p.getX() + disX; x++) {
            for (int y = p.getY() - disY; y <= p.getY() + disY; y++) {
                led.brightness += getPixelBrightness(x, y);
            }
        }
        return led.brightness;
    }


    @Getter
    @Setter
    @Accessors(chain = true)
    public static class Params {
        private RecImage ledPhoto;
        private RecImage blackPhoto;
        private List<IntPoint> fence;
        private Matrix<LedNode> leds;
        private Matrix<double[]> result;
        private int distanceX;
        private int distanceY;
        private int colorIdx;
        private int showBrightness;
        private int span;
        private int k = 1;
    }

}
